
#pragma used+
sfrb PINB=3;
sfrb DDRB=4;
sfrb PORTB=5;
sfrb PINC=6;
sfrb DDRC=7;
sfrb PORTC=8;
sfrb PIND=9;
sfrb DDRD=0xa;
sfrb PORTD=0xb;
sfrb TIFR0=0x15;
sfrb TIFR1=0x16;
sfrb TIFR2=0x17;
sfrb PCIFR=0x1b;
sfrb EIFR=0x1c;
sfrb EIMSK=0x1d;
sfrb GPIOR0=0x1e;
sfrb EECR=0x1f;
sfrb EEDR=0x20;
sfrb EEARL=0x21;
sfrb EEARH=0x22;
sfrw EEAR=0x21;   
sfrb GTCCR=0x23;
sfrb TCCR0A=0x24;
sfrb TCCR0B=0x25;
sfrb TCNT0=0x26;
sfrb OCR0A=0x27;
sfrb OCR0B=0x28;
sfrb GPIOR1=0x2a;
sfrb GPIOR2=0x2b;
sfrb SPCR=0x2c;
sfrb SPSR=0x2d;
sfrb SPDR=0x2e;
sfrb ACSR=0x30;
sfrb SMCR=0x33;
sfrb MCUSR=0x34;
sfrb MCUCR=0x35;
sfrb SPMCSR=0x37;
sfrb SPL=0x3d;
sfrb SPH=0x3e;
sfrb SREG=0x3f;
#pragma used-

#asm
	#ifndef __SLEEP_DEFINED__
	#define __SLEEP_DEFINED__
	.EQU __se_bit=0x01
	.EQU __sm_mask=0x0E
	.EQU __sm_adc_noise_red=0x02
	.EQU __sm_powerdown=0x04
	.EQU __sm_powersave=0x06
	.EQU __sm_standby=0x0C
	.SET power_ctrl_reg=smcr
	#endif
#endasm

extern void extern_int_set(unsigned char num,unsigned char en,unsigned char mode);

extern void timer0_set(unsigned char ms);

extern void uart_set(unsigned char uart_en,unsigned char uart_int_en,unsigned char baud);

#pragma used+

void delay_us(unsigned int n);
void delay_ms(unsigned int n);

#pragma used-

extern void SEI(void);	

extern void CLI(void); 

extern void ENTER_CRITICAL(void);

extern void EXIT_CRITICAL(void); 

extern void open_led(void);	

extern void close_led(void);	

extern void toggle_led(void);	

typedef struct S_RF_SETTINGS {
unsigned char FSCTRL1; 
unsigned char FSCTRL0; 
unsigned char FREQ2; 
unsigned char FREQ1; 
unsigned char FREQ0; 
unsigned char MDMCFG4; 
unsigned char MDMCFG3; 
unsigned char MDMCFG2; 
unsigned char MDMCFG1; 
unsigned char MDMCFG0; 
unsigned char CHANNR; 
unsigned char DEVIATN; 
unsigned char FREND1; 
unsigned char FREND0; 
unsigned char MCSM0; 
unsigned char FOCCFG; 
unsigned char BSCFG; 
unsigned char AGCCTRL2; 
unsigned char AGCCTRL1; 
unsigned char AGCCTRL0; 
unsigned char FSCAL3; 
unsigned char FSCAL2; 
unsigned char FSCAL1; 
unsigned char FSCAL0; 
unsigned char FSTEST; 
unsigned char TEST2; 
unsigned char TEST1; 
unsigned char TEST0; 
unsigned char FIFOTHR; 
unsigned char IOCFG2; 
unsigned char IOCFG0; 
unsigned char PKTCTRL1; 
unsigned char PKTCTRL0; 
unsigned char ADDR; 
unsigned char PKTLEN; 
} RF_SETTINGS;

extern void CS(void); 
extern void DCS(void); 

extern unsigned char cc_send_read(unsigned char sdata); 

extern void cc1100_init(unsigned char freq,unsigned char ch, unsigned char mode, unsigned char white,
unsigned char packet_limit); 

extern void rf_send_packet(unsigned char *txBuffer, unsigned char size);

extern unsigned char rf_receive_packet(unsigned char *rxBuffer,
unsigned char *length);

extern void rf_change_tx_power(unsigned char power);

extern void rf_change_channel(unsigned char ch); 

extern void start_receive(void);

extern void rf_idle(void);

extern void flush_rx_fifo(void);

extern void base_freq_cw_test(void); 

typedef struct {
unsigned short fifo_depth;
unsigned short fifo_read_point;
unsigned short fifo_write_point;
unsigned short fifo_used;
unsigned char   *fifo_data;
} FIFO_STRUCT;

extern void ENTER_CRITICAL(); 
extern void EXIT_CRITICAL(); 

void FIFO_init(FIFO_STRUCT *fifo); 
void FIFO_flush(FIFO_STRUCT *fifo);
unsigned char FIFO_read(FIFO_STRUCT *fifo, unsigned char   *data);
unsigned char FIFO_write(FIFO_STRUCT *fifo, unsigned char   *data);
unsigned short FIFO_get_free_size(FIFO_STRUCT *fifo);
unsigned short FIFO_get_used_size(FIFO_STRUCT *fifo);

unsigned char base_freq;

void CS(void){
PORTB.2 = 0;
}

void DCS(void){
PORTB.2 = 1;
}

unsigned char cc_send_read(unsigned char sdata){

SPDR =  sdata;  
while(0 == (SPSR & (1<<7))); 
sdata = SPDR;
return(sdata);
}

unsigned char MISO_WAIT() {

unsigned short i;

for(i=0;i<3000;i++)
{
if(0 == PINB.4)
{
return 1;
}
}

return 0;
}

void halSpiWriteBurstReg(unsigned char addr, unsigned char *buffer,
unsigned char count) {
unsigned long i;

CS();
MISO_WAIT();
i = addr | 0x40;
cc_send_read(i);
cc_send_read(count);
for (i = 0; i < count; i++) {
cc_send_read(buffer[i]);
}
DCS();
}
void halSpiWriteReg(unsigned char addr, unsigned char value) {

CS();
MISO_WAIT();
cc_send_read(addr);
cc_send_read(value);
DCS();
}

flash RF_SETTINGS FSK_38K4 = {

0x08, 
0x00, 
0x21, 
0x7B, 
0x13, 
0xCA, 
0x83, 
0x83, 
0x22, 
0xF8, 
0x00, 
0x34, 
0x56, 
0x10, 
0x18, 
0x16, 
0x6C, 
0x43, 
0x40, 
0x91, 
0xE9, 
0x2A, 
0x00, 
0x1F, 
0x59, 
0x81, 
0x35, 
0x09, 
0x07, 
0x29, 
0x06, 
0x04, 
0x05, 
0x00, 
0xFF 
};

flash RF_SETTINGS FSK_1K_2 = {

0x06, 
0x00, 
0x21, 
0x7B, 
0x13, 
0xF5, 
0x83, 
0x03, 
0x22, 
0xF8, 
0x00, 
0x15, 
0x56, 
0x10, 
0x18, 
0x16, 
0x6C, 
0x03, 
0x40, 
0x91, 
0xE9, 
0x2A, 
0x00, 
0x1F, 
0x59, 
0x81, 
0x35, 
0x09, 
0x07, 
0x29, 
0x06, 
0x04, 
0x05, 
0x00, 
0xff 
};

flash RF_SETTINGS FSK_100K = {

0x08, 
0x00, 
0x21, 
0x7B, 
0x13, 
0x5B, 
0xF8, 
0x03, 
0x22, 
0xF8, 
0x00, 
0x47, 
0xB6, 
0x10, 
0x18, 
0x1D, 
0x1C, 
0xC7, 
0x00, 
0xB2, 
0xEA, 
0x2A, 
0x00, 
0x1F, 
0x59, 
0x81, 
0x35, 
0x09, 
0x07, 
0x29, 
0x06, 
0x04, 
0x05, 
0x00, 
0xff 
};

flash RF_SETTINGS MSK_250K = {

0x0A, 
0x00, 
0x21, 
0x7B, 
0x13, 
0x2D, 
0x3B, 
0x73, 
0x22, 
0xF8, 
0x00, 
0x00, 
0xB6, 
0x10, 
0x18, 
0x1D, 
0x1C, 
0xC7, 
0x00, 
0xB0, 
0xEA, 
0x2A, 
0x00, 
0x1F, 
0x59, 
0x88, 
0x31, 
0x09, 
0x07, 
0x29, 
0x06, 
0x04, 
0x05, 
0x00, 
0xff 
};

flash RF_SETTINGS MSK_500K = {
0x0D,   
0x00,   
0x10,   
0xA7,   
0x62,   
0x0E,   
0x3B,   
0x73,   
0x42,   
0xF8,   
0x00,   
0x00,   
0xB6,   
0x10,   
0x18,   
0x1D,   
0x1C,   
0xC7,   
0x00,   
0xB0,   
0xEA,   
0x2A,   
0x00,   
0x1F,   
0x59,   
0x88,   
0x31,   
0x09,   
0x07,   
0x29,   
0x06,   
0x04,   
0x05,   
0x00,   
0xFF    
};

unsigned char paTable[] = { 0x60 };

void halRfWriteRfSettings(flash RF_SETTINGS *pRfSettings) {
halSpiWriteReg(0x0B        , pRfSettings->FSCTRL1);
halSpiWriteReg(0x0C        , pRfSettings->FSCTRL0);
halSpiWriteReg(0x0D        , pRfSettings->FREQ2);
halSpiWriteReg(0x0E        , pRfSettings->FREQ1);
halSpiWriteReg(0x0F        , pRfSettings->FREQ0);
halSpiWriteReg(0x10        , pRfSettings->MDMCFG4);
halSpiWriteReg(0x11        , pRfSettings->MDMCFG3);
halSpiWriteReg(0x12        , pRfSettings->MDMCFG2);
halSpiWriteReg(0x13        , pRfSettings->MDMCFG1);
halSpiWriteReg(0x14        , pRfSettings->MDMCFG0);
halSpiWriteReg(0x0A        , pRfSettings->CHANNR);
halSpiWriteReg(0x15        , pRfSettings->DEVIATN);
halSpiWriteReg(0x21        , pRfSettings->FREND1);
halSpiWriteReg(0x22        , pRfSettings->FREND0);
halSpiWriteReg(0x18         , pRfSettings->MCSM0);
halSpiWriteReg(0x19        , pRfSettings->FOCCFG);
halSpiWriteReg(0x1A        , pRfSettings->BSCFG);
halSpiWriteReg(0x1B        , pRfSettings->AGCCTRL2);
halSpiWriteReg(0x1C        , pRfSettings->AGCCTRL1);
halSpiWriteReg(0x1D        , pRfSettings->AGCCTRL0);
halSpiWriteReg(0x23        , pRfSettings->FSCAL3);
halSpiWriteReg(0x24        , pRfSettings->FSCAL2);
halSpiWriteReg(0x25        , pRfSettings->FSCAL1);
halSpiWriteReg(0x26        , pRfSettings->FSCAL0);
halSpiWriteReg(0x29        , pRfSettings->FSTEST);
halSpiWriteReg(0x2C        , pRfSettings->TEST2);
halSpiWriteReg(0x2D        , pRfSettings->TEST1);
halSpiWriteReg(0x2E        , pRfSettings->TEST0);
halSpiWriteReg(0x03        , pRfSettings->FIFOTHR);
halSpiWriteReg(0x00        , pRfSettings->IOCFG2);
halSpiWriteReg(0x02        , pRfSettings->IOCFG0);
halSpiWriteReg(0x07        , pRfSettings->PKTCTRL1);
halSpiWriteReg(0x08        , pRfSettings->PKTCTRL0);
halSpiWriteReg(0x09        , pRfSettings->ADDR);
halSpiWriteReg(0x06        , pRfSettings->PKTLEN);
}
void halSpiReadBurstReg(unsigned char addr, unsigned char *buffer,
unsigned char count) {
unsigned long i;

CS();
MISO_WAIT();
i = (addr | 0xC0);
cc_send_read(i);
for (i = 0; i < count; i++) {
buffer[i] = cc_send_read(0);
}
DCS();
}
unsigned char halSpiReadReg(unsigned char addr) {
unsigned char x;

CS();
MISO_WAIT();
x = (addr | 0x80);
cc_send_read(x);
x = cc_send_read(0);
DCS();
return x;
}
unsigned char halSpiReadStatus(unsigned char addr) {
unsigned char x;

CS();
MISO_WAIT();
x = (addr | 0xC0);
cc_send_read(addr | 0xC0);
x = cc_send_read(0);
DCS();
return x;
}
void halSpiStrobe(unsigned char strobe) {
CS();
MISO_WAIT();
cc_send_read(strobe);
DCS();
}

void start_transmit(void) {
ENTER_CRITICAL();
halSpiStrobe(0x35        );
EXIT_CRITICAL();
}

void start_receive(void) {
ENTER_CRITICAL();
halSpiStrobe(0x34        );
EXIT_CRITICAL();
}

void rf_idle(void) {
ENTER_CRITICAL();
halSpiStrobe(0x36        );
EXIT_CRITICAL();
}

void flush_rx_fifo(void) {
halSpiStrobe(0x3A        );
}

void rf_send_packet(unsigned char *txBuffer, unsigned char size) {

rf_idle();

flush_rx_fifo();

halSpiWriteBurstReg(0x3F, txBuffer, size);
start_transmit();
}

unsigned char rf_receive_packet(unsigned char *rxBuffer, unsigned char *length) {
unsigned char status[2];
unsigned char packetLength;

if (halSpiReadStatus(0x3B) & 0x7F) {

packetLength = halSpiReadReg(0x3F);

if (packetLength <= *length) {
halSpiReadBurstReg(0x3F, rxBuffer, packetLength);
*length = packetLength;

halSpiReadBurstReg(0x3F, status, 2);

return (status[1] & 0x80);
} else {
*length = packetLength;

halSpiStrobe(0x3A        );
return 0;
}
} else
return 0;
}

void Reset_CCxx00(void) {

DCS();
delay_ms(1);
CS();
delay_ms(1);
DCS();
delay_ms(1);
CS();
MISO_WAIT();
cc_send_read(0x30        );
MISO_WAIT();
DCS();
}

void rf_change_tx_power(unsigned char power) {
rf_idle();
switch (base_freq) {
case 2:
if (0   == power) {
halSpiWriteReg(0x3e, 0x8e); 
} else if (1   == power) {
halSpiWriteReg(0x3e, 0x85); 
} else {
halSpiWriteReg(0x3e, 0xc3); 
}
break;
case 1:
if (0   == power) {
halSpiWriteReg(0x3e, 0x60); 
} else if (1   == power) {
halSpiWriteReg(0x3e, 0x85); 
} else {
halSpiWriteReg(0x3e, 0xc0); 
}
break;
case 0:
if (0   == power) {
halSpiWriteReg(0x3e, 0x60); 
} else if (1   == power) {
halSpiWriteReg(0x3e, 0x85); 
} else {
halSpiWriteReg(0x3e, 0xc2); 
}
break;
case 3:
if (0   == power) {
halSpiWriteReg(0x3e, 0x8e); 
} else if (1   == power) {
halSpiWriteReg(0x3e, 0x83); 
} else {
halSpiWriteReg(0x3e, 0xc0); 
}
break;
default:
break;
}
}

void rf_change_channel(unsigned char ch) {
if (ch > 9)
return;
rf_idle();
halSpiWriteReg(0x0A        , ch);
halSpiStrobe(0x33        );
delay_ms(1); 
}

void ctr_data_whitening(unsigned char en) {
unsigned char tmp;
tmp = halSpiReadReg(0x08        );
if (en) {
tmp |= (1 << 6);
} else {
tmp &= ~(1 << 6);
}
halSpiWriteReg(0x08        , tmp);
}

void rf_mode_set(unsigned char mode) {
switch (mode) {
case 0 :
halRfWriteRfSettings(&FSK_1K_2);
break;
case 1 :
halRfWriteRfSettings(&FSK_38K4);
break;
case 2 :
halRfWriteRfSettings(&FSK_100K);
break;
case 3 :
halRfWriteRfSettings(&MSK_250K);
break;
case 4 :
halRfWriteRfSettings(&MSK_500K);
break;
default:break;
}
switch (base_freq) {
case 0: 
halSpiWriteReg(0x0D        , 0x0c);
halSpiWriteReg(0x0E        , 0x1d);
halSpiWriteReg(0x0F        , 0x89);
break;
case 1: 
halSpiWriteReg(0x0D        , 0x10);
halSpiWriteReg(0x0E        , 0xa7);
halSpiWriteReg(0x0F        , 0x62);
break;
case 2: 
halSpiWriteReg(0x0D        , 0x21);
halSpiWriteReg(0x0E        , 0x7B);
halSpiWriteReg(0x0F        , 0x13);

break;
case 3: 
halSpiWriteReg(0x0D        , 0x23);
halSpiWriteReg(0x0E        , 0x31);
halSpiWriteReg(0x0F        , 0x3b);
break;
default:break;
}
}

void cc1100_init(unsigned char freq,unsigned char ch, unsigned char mode, unsigned char white,
unsigned char packet_limit) {

base_freq = freq;		
Reset_CCxx00();												
rf_mode_set(mode);												
if((packet_limit>62)&&(packet_limit<0xff)) packet_limit = 62;	
if ((0 == packet_limit) || 0xff == packet_limit) {
halSpiWriteReg(0x06        , 0xff);
} else {
halSpiWriteReg(0x06        , packet_limit);
}

rf_change_channel(ch);											
ctr_data_whitening(white);										
halSpiWriteBurstReg(0x3E, paTable, sizeof(paTable));	
rf_change_tx_power(2  );								
halSpiStrobe(0x33        );										
delay_ms(1); 

halSpiWriteReg(0x00        , 0x06);
halSpiWriteReg(0x02        , 0x06);

rf_idle();
}

void base_freq_cw_test(void){
rf_idle();
rf_change_channel(0);
ctr_data_whitening(0);
halSpiWriteReg(0x08        , 0x02);	
halSpiWriteReg(0x12        , 0x30);	
halSpiStrobe(0x35        );				

}

